home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / byte0887.arc / LANE.ARC / PREDS80.ARI < prev    next >
Text File  |  1987-05-05  |  6KB  |  234 lines

  1. % Subject: PREDS80.ARI  - from A. Lane: "Simulating an 8085 with Prolog"
  2.  
  3. %  bit_xor(A,B,C) :: C is exclusive-or of A and B
  4. %
  5.  
  6. bit_xor(0,0,0) :- !.
  7. bit_xor(0,1,1) :- !.
  8. bit_xor(1,0,1) :- !.
  9. bit_xor(1,1,0) :- !.
  10. bit_xor(A,B,X) :-
  11.         AA0 is A // 2,        A0 is A mod 2,
  12.         BB0 is B // 2,        B0 is B mod 2,
  13.         bit_xor(AA0,BB0,XX0),
  14.         bit_xor(A0,B0,X0),
  15.         X is 2 * XX0 + X0.
  16.  
  17. %  adjust_flags( In, Out, flags(Z,S,P,CY,AC)) :: In --> Out and flags checked.
  18. %
  19.  
  20. adjust_flags(A,In, Out, flags(Z,S,P,CY,AC)) :-
  21.         check_carry( In, Out, CY ),
  22.         check_zero(Out,Z),
  23.         check_parity(Out,P),
  24.         check_aux_carry(A,Out,AC),
  25.         check_sign(Out,S).
  26.  
  27. %  carry_on ::  PC <-- PC + 2.
  28. %
  29.  
  30. carry_on :-
  31.         retract(state(Regs,PC,SP,Flags)),
  32.         NewPC is PC + 2,
  33.         asserta(state(Regs,NewPC,SP,Flags)).
  34.  
  35. % check_zero(A,B) ::  A == 0 --> B == 1, else B == 0.
  36. %
  37.  
  38. check_zero(0,1) :- !.
  39. check_zero(_,0).
  40.  
  41. % check_parity(X,Y) :: Y reflects odd parity of number of bits in X.
  42.  
  43. check_parity(X,Y) :- par(X,T), Y is T mod 2, !.
  44.  
  45. par(0,0) :- !.
  46. par(1,1) :- !.
  47. par(N,P) :-  J is N mod 2,
  48.              K is N // 2,
  49.              par(K,P1),
  50.              P is J + P1.
  51.  
  52. check_sign(X,1) :- X > 127, !.
  53. check_sign(_,0).
  54.  
  55. check_carry(In,Out,1) :- In > 255, Out is In - 255, !.
  56. check_carry(In,Out,1) :- In < 0,   Out is In + 255, !.
  57. check_carry(In, In,0).
  58.  
  59. check_aux_carry(OldAccum, NewAccum, 1) :-
  60.         OldAccum /\ 24 =:= 8,      %  old bit 3 on and old bit 4 off
  61.         NewAccum /\ 24 =:= 16,!.   %  new bit 4 on and new bit 3 off
  62.                    %  (=:= evaluates both sides and tests for equality)
  63.  
  64. check_aux_carry(_,_,0) :- !.
  65.  
  66. zero_flag_is_set :-
  67.         state(_,_,_,flags(1,_,_,_,_)), !.
  68.  
  69. sign_flag_is_set :-
  70.         state(_,_,_,flags(_,1,_,_,_)), !.
  71.  
  72. parity_flag_is_set :-
  73.         state(_,_,_,flags(_,_,1,_,_)), !.
  74.  
  75. carry_flag_is_set :-
  76.         state(_,_,_,flags(_,_,_,1,_)), !.
  77.  
  78. aux_carry_flag_is_set :-
  79.         state(_,_,_,flags(_,_,_,_,1)), !.
  80.  
  81. % reset (N) :: store PC on stack, PC <-- 8 * N.
  82. %
  83.  
  84. reset(N) :-
  85.      retract(state(Registers,PC,SP,Flags)),
  86.      decompose(PC,PCH,PCL),
  87.      Hi is SP - 1,
  88.      put_mem(Hi,PCH),
  89.      NewSP is SP - 2,
  90.      put_mem(NewSP,PCL),
  91.      NewPC is 8 * N,
  92.      asserta(state(Registers,NewPC,NewSP,Flags)).
  93.  
  94. % return :: pop PC off stack, adjust SP.
  95. %
  96.  
  97. return :-
  98.         retract(state(Registers,_,SP,Flags)),
  99.         get_mem(SP,PCL),
  100.         Hi is SP + 1,
  101.         get_mem(Hi,PCH),
  102.         PC is 256 * PCH + PCL,
  103.         NewSP is SP + 2,
  104.         asserta(state(Registers,PC,NewSP,Flags)).
  105.  
  106. jump :-
  107.         retract(state(Registers,PC,SP,Flags)),
  108.         get_mem(PC,PCL),
  109.         Hi is PC + 1,
  110.         get_mem(Hi,PCH),
  111.         NewPC is 256 * PCH + PCL,
  112.         asserta(state(Registers,NewPC,SP,Flags)).
  113.  
  114. call :-
  115.         retract(state(Registers,PC,SP,Flags)),
  116.         PCN is PC + 2,        % here? or on return?
  117.         PCH is PCN // 256,
  118.         PCL is PCN mod 256,
  119.         SP1 is SP - 1,
  120.         SP2 is SP - 2,
  121.         put_mem(SP1,PCH),
  122.         put_mem(SP2,PCL),
  123.         get_mem(PC,NPCL),
  124.         Hi is PC + 1,
  125.         get_mem(Hi,NPCH),
  126.         NewPC is 256 * NPCH + NPCL,
  127.         asserta(state(Registers,NewPC,SP2,Flags)).
  128.  
  129. % put_mem( H, L, Data) :: store Data in Address <-- 256 * H + L.
  130. %
  131.  
  132. put_mem( Hi, Lo, NewData ) :-
  133.         Address is 256 * Hi + Lo,
  134.         put_mem(Address, NewData).
  135.  
  136. % put_mem( H, L, Data) :: store Data in Address.
  137. %
  138.  
  139. put_mem(Address,NewData) :-
  140.         retract(memory(Address,_)),
  141.         asserta(memory(Address,NewData)).
  142.  
  143. % get_mem( H, L, Data) :: fetch Data in Address <-- 256 * H + L.
  144. %
  145.  
  146. get_mem(Hi, Lo, Data ) :-
  147.         Address is 256 * Hi + Lo,
  148.         get_mem(Address,Data).
  149.  
  150. % get_mem( Address, Data) :: fetch Data in Address.
  151. %
  152.  
  153. get_mem(Address, Data) :-
  154.         memory(Address,Data).
  155.  
  156. %  decompose(Address, Hibyte, Lobyte) :: Address <-- 256 * Hibyte + Lobyte
  157. %    (o,i,i)
  158. %
  159.  
  160. decompose(Address, Hibyte, Lobyte) :-   % (o,i,i)
  161.         var(Address),    % if Address is uninstantiated
  162.         Address is 256 * Hibyte + Lobyte.
  163.  
  164. %  decompose(Address, Hibyte, Lobyte) :: Address --> Hibyte ; Lobyte
  165. %    (i,o,o)
  166. %
  167.  
  168. decompose(Address, Hibyte, Lobyte) :-   % (i,o,o)
  169.         F is Address / 256,
  170.         H is integer(F),
  171.         Hibyte is H /\ 255,
  172.         G is Address - 256 * H,
  173.         Lobyte is integer(G).
  174.  
  175. put_address(Lo) :-            % write an address in hex
  176.      decompose(Lo,LoH,LoL),
  177.      dec_hex_byte(LoH,LHH),
  178.      dec_hex_byte(LoL,LLH),
  179.      write(LHH),write(LLH),write(' : '),!.
  180.  
  181. %    Decimal-to-hex and Hex-to-decimal Conversions.
  182. %
  183.  
  184. dec_hex_byte( Dec, Hex ) :-   % (i,o)
  185.      var(Hex),!,
  186.      Dec < 256,
  187.      Hi is Dec >> 4,
  188.      Lo is Dec /\ 15,
  189.      d_h(Hi,H),
  190.      d_h(Lo,L),
  191.      list_text([H,L],Hex).
  192.  
  193. dec_hex_byte( Dec, Hex ) :-   % (o,i)
  194.      list_text([H,L],Hex),
  195.      d_h(Hi,H),
  196.      d_h(Lo,L),
  197.      Dec is 16 * Hi + Lo,!.
  198.  
  199. d_h( In, Out ) :-   % (i,o)
  200.      In < 10,
  201.      Out is In + 48.
  202.  
  203. d_h( In, Out ) :-   % (i,o)
  204.      Out is In + 55.
  205.  
  206. d_h( Out, In ) :-   % (o,i)
  207.      In < 65,
  208.      Out is In - 48.
  209.  
  210. d_h( Out, In ) :-   % (o,i)
  211.      In < 71,
  212.      Out is In - 55.
  213.  
  214.  
  215. min(I1,I1,I2) :- I1 =< I2, !.
  216. min(I2,I1,I2) :- I2 < I1.
  217.  
  218. for(X,X,X) :- !.
  219. for(X,Y,X).
  220. for(X,Y,Z) :- X1 is X + 1, for(X1,Y,Z).
  221.  
  222. append([H|T], L, [H|R]) :- !, append(T, L, R).
  223. append([], L, L).
  224.  
  225. valid_adr(H,L) :- top_of_memory(TOM), TOM >= (256 * H + L).
  226.  
  227. reg(a,1).      reg(b,2).      reg(c,3).      reg(d,4).
  228. reg(e,5).      reg(h,6).      reg(l,7).
  229.  
  230. fl(z,1).       fl(s,2).       fl(p,3).       fl(cy,4).      fl(ac,5).
  231.  
  232. %
  233. % end: PREDS80.ARI
  234.